package xml.parserDOM;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



//import xml.SAXHandler;
import xml.SAXHandler;
import xml.parserSAX.SAXException;

import Clases.Atributo;
import Clases.Tag;

/* @author Ficuss
 *
 */
public abstract class GenerarDOM {


	/**
	 * Funcion que se encarga de generar el arbolDom a traves del String pasado
	 * por parametro
	 * 
	 * @param file
	 * @param sax
	 * @return
	 * @throws SaxException
	 */
	public static Arbol generarDOM(String[] file,SAXHandler sax) throws SAXException {

		//Lista para asiganacion de hijos a padres.
		ArrayList<xml.parserDOM.Nodo<Tag>> pila = new ArrayList<Nodo<Tag>>();
		
		boolean isFirst = true;
		Arbol arbol = new Arbol();
		//arbol = null;
		String regex = "<\\?xml.*>|<(\\w+)>|<(\\w+) (\\w+)=\"(\\w+)\">|</(\\w+)>|<!DOCTYPE (\\w+) SYSTEM \"(.*)\">|<!-- (\\w+)";
		//compilamos el patron
		Pattern pattern = Pattern.compile(regex);
	
		// recorro el archivo xml linea a linea
		Integer countLine =0;
		for (String line : file) {
			countLine++;
			Matcher matcher = pattern.matcher(line);
			matcher.find();
			//creo el nodo
			Nodo<Tag> nodo = new Nodo<Tag>();
			Tag tag = new Tag();
			Atributo atr;
			//controla los tag sin atributos
			try {
			if (matcher.group(1) != null) {
				//asigano el nombre del tag al tag
				tag.setQname(matcher.group(1));
				nodo.setTag(tag);
				//asigano a la pila el nodo creado;
				pila.add(nodo);
				
				sax.startElement(matcher.group(1).toString(), null);
				if (isFirst) {
					// creo un arbol para tag sin atributos
					
					isFirst = false;
					arbol.setRootElement(nodo);
				}else{
					//referrencio al objeto anterior de la pila y 
					//cargo en su lista de hijos el ultimo objeto de la pila 
					//que es el ultimo que se creeo
					pila.get(pila.size()-2).addChild(pila.get(pila.size()-1));
					}
				System.out.println(matcher.group(1));
			} else {
				//controla los tag con atributos
				if (matcher.group(2) != null) {
					//Asingno nombre del tag al tag
					tag.setQname(matcher.group(2));
					//creo elatributo del nodo
					atr = new Atributo();
					atr.setNombre(matcher.group(3));
					atr.setValor(matcher.group(4));
					tag.addAtributo(atr);
					//seteo al nodo su tag
					nodo.setTag(tag);
					//asigano a la pila el nodo creado;
					pila.add(nodo);
					sax.startElement(matcher.group(2), atr);
					// la primera vez agrega el nodo al arbol
					if (isFirst) {
						//arbol = new Arbol();
						isFirst = false;						
						arbol.setRootElement(nodo);
					}else{
						//referrencio al objeto anterior de la pila y 
						//cargo en su lista de hijos el ultimo objeto de la pila 
						//que es el ultimo que se creeo
						pila.get(pila.size()-2).addChild(pila.get(pila.size()-1));
					}
					System.out.println(matcher.group(2));
				}
				if (matcher.group(5) != null) {
					System.out.println(matcher.group(5));
					sax.endElement(null, null, matcher.group(5));
					pila.remove(pila.size()-1);
				}
			}	
				if (matcher.group(6) != null) {
				System.out.println(matcher.group(6));
				System.out.println(matcher.group(7));
				arbol.setDocType( matcher.group(6));
				arbol.setDocInfo(matcher.group(7));
				}
				if (matcher.group(8) != null) {
                    System.out.println("lee el comentario: " + matcher.group(8));
				}
			} catch (IllegalStateException ise) {
				String pat = "<(\\w+)>(.*)</(\\w+)>";
                Pattern patron = Pattern.compile(pat);

                String lineaCompleta = file[countLine - 2].toString()
                                + file[countLine - 1].toString()
                                + file[countLine].toString();

                Matcher mat = patron.matcher(lineaCompleta);
                mat.find();
                try{
                if (mat.group(1).equals(mat.group(3))) {
                        if (mat.group(2) != null) {
                                pila.get(pila.size() - 1).setDato(line);
                                // seteo datos del tag xml.
                                sax.characters(line);
                        }
                }
                }catch (IllegalStateException ex)
                {
                	throw new SAXException(SAXException.Tipo.FATAL_ERROR,"Error de Sintaxis:  "+ line );
                }
			}catch (NumberFormatException e) {
            	throw new SAXException(SAXException.Tipo.FATAL_ERROR,"Error de Sintaxis:  "+ line );
			}catch (NullPointerException e) {
            	throw new SAXException(SAXException.Tipo.FATAL_ERROR,"Error de Sintaxis:  "+ line );
			}

		}
		if(!pila.isEmpty() || pila.size()!=0){
			throw new SAXException(SAXException.Tipo.FATAL_ERROR,"El XML se encuentra mal formado: TAG: "+pila.get(0).getData().getQname());
		}
		return arbol;
	}	


}
